﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.NetworkInformation;
using System.ComponentModel;
using Microsoft.Forums.SyncService;

namespace Microsoft.Forums.ForumsClient.Models
{
    /// <summary>
    ///  NetworkConnection
    /// </summary>
    public class NetworkConnection : BindableObject, IConnection
    {
        /// <summary>
        ///  Reference to the active network interface.
        /// </summary>
        private NetworkInterface activeAdapter;

        /// <summary>
        ///  Return the active network interface for additional information like network name etc.
        /// </summary>
        public NetworkInterface ConnectedNetwork
        {
            get
            {
                return activeAdapter;
            }
        }

        /// <summary>
        ///  Determines if you have internet connectivity.
        /// </summary>
        public bool IsConnected
        {
            get
            {
                return (activeAdapter != null && activeAdapter.OperationalStatus == OperationalStatus.Up);
            }
        }

        /// <summary>
        ///  Subscribe to any change in network status & detect the active adapter.
        /// </summary>
        public NetworkConnection()
        {
            NetworkChange.NetworkAvailabilityChanged += NetworkChange_NetworkAvailabilityChanged;
            NetworkChange.NetworkAddressChanged += NetworkChange_NetworkAddressChanged;

            DetectConnectedNetwork();
        }

        /// <summary>
        ///  Detect the active network.
        ///  Make sure it's not loopback, not a tunnel. Maybe have to test / update this
        ///  on dial up connection.
        /// </summary>
        private void DetectConnectedNetwork()
        {
            activeAdapter = null;
            foreach (NetworkInterface networkAdapter in NetworkInterface.GetAllNetworkInterfaces())
            {
                if (networkAdapter.NetworkInterfaceType != NetworkInterfaceType.Loopback &&
                    networkAdapter.NetworkInterfaceType != NetworkInterfaceType.Tunnel &&
                    networkAdapter.OperationalStatus == OperationalStatus.Up)
                {
                    activeAdapter = networkAdapter;
                }
            }
        }

        /// <summary>
        ///  On Network address changed redetect the active adapter and also raise state change event.
        /// </summary>
        /// <param name="sender">sender who notified this object</param>
        /// <param name="e">Event Arguments</param>
        private void NetworkChange_NetworkAddressChanged(object sender, EventArgs e)
        {
            DetectConnectedNetwork();
            OnPropertyChanged("IsConnected");
        }

        /// <summary>
        ///  On network availability Change
        /// </summary>
        /// <param name="sender">sender who notified this object</param>
        /// <param name="e">Event Arguments</param>
        private void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e)
        {
            DetectConnectedNetwork();
            OnPropertyChanged("IsConnected");
        }
    }
}
